const trimReg = /^\u0000+|\u0000+$/g;

/**
 * 将unsigned number转换为Big-Endian buffer
 * @param number
 * @param bytes buffer的字节数
 */
export function number2Buffer(number: number, bytes: number = 8): Buffer {
	if (number < 0) {
		throw new Error('"number" must be greater than or equal to zero.');
	}

	// 转换为16进制字符串
	let hex = number.toString(16);

	// ------- 将hex length补充成bytes x 2，不足则高位补0，超过则去掉高位
	const length = hex.length;
	const targetLength = bytes * 2;
	if (length < targetLength) {
		hex = hex.padStart(targetLength, '0');
	} else if (length > targetLength) {
		hex = hex.substring(length - targetLength);
	}

	// ------ 填充到buffer里，高位在前
	const buffer = Buffer.alloc(bytes);
	for (let offset = 0; offset < bytes; offset++) {
		const bn = Number("0x" + hex.substring(offset * 2, (offset * 2) + 2));
		buffer.writeUInt8(bn, offset);
	}

	return buffer;
}

/**
 * 将buf转为数字
 * @param buf
 * @param offset
 * @returns {number}
 */
export function buffer2Number(buf: Buffer, offset: number): number {
	const str = buf.toString('hex', offset, offset + 8);
	const v = parseInt(str.substring(8), 16) - parseInt(str.substring(0, 8), 16);
	return v < 0 ? v - 1 : v;
}

/**
 * 将buf转为短数字
 * @param buf
 * @param offset
 * @returns {number}
 */
export function buffer2ShortNumber(buf: Buffer, offset: number): number {
	const str = buf.toString('hex', offset, offset + 4);
	const v = parseInt(str.substring(4), 16) - parseInt(str.substring(0, 4), 16);
	return v < 0 ? v - 1 : v;
}

/**
 * 构造Object.defineProperty中指定的property属性，并达到const声明的效果，只读，不可写
 * @param value
 * @returns {{configurable: boolean, writable: boolean, value: *}}
 */
export function buildConstProp(value: any): PropertyDescriptor {
	return {
		configurable: false,
		writable: false,
		value: value
	};
}

/**
 * 在String.prototype.trim的基础上再去掉\u0000
 *  默认trim的处理见下:
 *      https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/trim
 *      http://blog.stevenlevithan.com/archives/faster-trim-javascript
 *      http://jsperf.com/mega-trim-test
 * @param str
 * @returns {string}
 */
export function trim(str: string): string {
	return str.trim().replace(trimReg, '');
}

/**
 * file id conver to group and filename
 * @param fileId
 * @returns {{group: string, filename: string}}
 */
export function id2gf(fileId: string): { group: string, filename: string } {
	const pos = fileId.indexOf('/');
	return {
		group: fileId.substring(0, pos),
		filename: fileId.substring(pos + 1)
	};
}
